package demoMod.invincibleOne.cards.invincible;

import basemod.BaseMod;
import com.megacrit.cardcrawl.actions.AbstractGameAction;
import com.megacrit.cardcrawl.actions.common.GainBlockAction;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.cards.CardGroup;
import com.megacrit.cardcrawl.characters.AbstractPlayer;
import com.megacrit.cardcrawl.core.CardCrawlGame;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.localization.CardStrings;
import com.megacrit.cardcrawl.monsters.AbstractMonster;
import com.megacrit.cardcrawl.rooms.MonsterRoom;
import demoMod.invincibleOne.InvincibleOneMod;
import demoMod.invincibleOne.actions.SelectCardInCardGroupAction;
import demoMod.invincibleOne.enums.CardTagsEnum;
import demoMod.invincibleOne.interfaces.IOnCurseAddToHand;

import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class Hologram extends AbstractInvincibleCard {
    public static final String ID = InvincibleOneMod.makeID("Hologram");

    private static final CardStrings cardStrings = CardCrawlGame.languagePack.getCardStrings(ID);
    public static final String NAME = cardStrings.NAME;
    public static final String DESCRIPTION = cardStrings.DESCRIPTION;
    public static final String IMG_PATH = "cards/Hologram.png";

    private static final CardType TYPE = CardType.SKILL;
    private static final CardRarity RARITY = CardRarity.UNCOMMON;
    private static final CardTarget TARGET = CardTarget.NONE;

    private static final int COST = -2;

    public Hologram() {
        super(ID, NAME, InvincibleOneMod.getResourcePath(IMG_PATH), COST, DESCRIPTION, TYPE, RARITY, TARGET);
        this.baseMagicNumber = this.magicNumber = 3;
        this.tags.add(CardTagsEnum.VIRUS);
    }

    @Override
    public Runnable getUpgradeAction() {
        return () -> {
            this.rawDescription = cardStrings.UPGRADE_DESCRIPTION;
            upgradeMagicNumber(2);
            this.initializeDescription();
        };
    }

    @Override
    public void use(AbstractPlayer p, AbstractMonster m) {
        if (upgraded) {
            addToBot(new SelectCardInCardGroupAction(1, c -> (c.hasTag(CardTagsEnum.VIRUS) || c.type == CardType.CURSE) && !c.cardID.equals(ID), c -> {
                if (p.hand.size() >= BaseMod.MAX_HAND_SIZE) {
                    p.createHandIsFullDialog();
                } else {
                    returnToHand(c);
                    if (c.hasTag(CardTagsEnum.VIRUS)) {
                        c.use(p, m);
                    }
                }
            }, p.discardPile, SelectCardInCardGroupAction.TEXT[2], false));
        } else {
            addToBot(new AbstractGameAction() {
                @Override
                public void update() {
                    List<AbstractCard> cards = p.discardPile.group.stream().filter(c ->
                            c.hasTag(CardTagsEnum.VIRUS) || c.type == CardType.CURSE).collect(Collectors.toList());
                    if (!cards.isEmpty()) {
                        Collections.shuffle(cards, new Random(AbstractDungeon.cardRandomRng.randomLong()));
                        AbstractCard card = cards.remove(0);
                        if (p.hand.size() >= BaseMod.MAX_HAND_SIZE) {
                            p.createHandIsFullDialog();
                        } else {
                            returnToHand(card);
                            if (card.hasTag(CardTagsEnum.VIRUS) && !card.cardID.equals(ID)) {
                                card.use(p, m);
                            }
                            IOnCurseAddToHand.curseAddToHand(card);
                        }
                    }

                    for (AbstractMonster m : AbstractDungeon.getMonsters().monsters) {
                        if (!m.isDeadOrEscaped()) {
                            addToBot(new GainBlockAction(m, m, magicNumber));
                        }
                    }
                    isDone = true;
                }
            });
        }
    }

    private void returnToHand(AbstractCard card) {
        card.unhover();
        card.lighten(true);
        card.setAngle(0.0F);
        card.drawScale = 0.12F;
        card.targetDrawScale = 0.75F;
        if (AbstractDungeon.player.drawPile.contains(card)) {
            card.current_x = CardGroup.DRAW_PILE_X;
        } else {
            card.current_x = CardGroup.DISCARD_PILE_X;
        }
        AbstractPlayer p = AbstractDungeon.player;
        card.current_y = CardGroup.DRAW_PILE_Y;
        p.discardPile.removeCard(card);
        p.hand.addToTop(card);
        p.hand.refreshHandLayout();
        p.hand.applyPowers();
    }
}
